package com.health.mapp.service;

import java.io.IOException;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;

public class SecureUtil {

	private static final String[] WORD_TABLE = {
		"de facto",
		"pectic",
		"decade",
		"brokerage",
		"panic",
		"dichloroethylene",
		"periodic",
		"frequency",
		"Fourier",
		"mixture"};
	
	private final static String iv = "Happy Holidays  ";
	
	public static String getChallenge(int index) {
		return WORD_TABLE[index];
	}
	
	public static String getCryptKey(String word) {
		String key = "";
		
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(word.getBytes());
			byte[] buffer = md5.digest();
			key = bcd2Str(buffer).substring(16);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return key;
	}
	
	private static String bcd2Str(byte[] bytes) {
		char temp[] = new char[bytes.length * 2], val;

		for (int i = 0; i < bytes.length; i++) {
			val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
			temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

			val = (char) (bytes[i] & 0x0f);
			temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
		}
		
		return new String(temp);
	}
	
	public static byte[] AESEncrypt(byte[] src, byte[] key, boolean ecbMode) {
		byte[] crypted = null;
		
		try {
			
			if (true == ecbMode) { // use ECB mode
				SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
				cipher.init(Cipher.ENCRYPT_MODE, keySpec);
				
				crypted = cipher.doFinal(src);
			} else { // use CBC mode
				SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
				Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
				IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
				cipher.init(Cipher.ENCRYPT_MODE, keySpec, ips);
				
				crypted = cipher.doFinal(src);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return crypted;
	}
	
	public static byte[] AESDecrypt(byte[] src, byte[] key, boolean ecbMode) {
		byte[] data = null;
		
		try {
			
			SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
			
			if (true == ecbMode) { // use ECB mode
				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
				cipher.init(Cipher.DECRYPT_MODE, keySpec);
				data = cipher.doFinal(src);
			} else { // use CBC mode
				Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
				IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
				cipher.init(Cipher.DECRYPT_MODE, keySpec, ips);
				data = cipher.doFinal(src);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return data;
	}
	
	/**
	 * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址;
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	public final static String getRemoteHost(HttpServletRequest request) throws IOException {
		// 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址

		String ip = request.getHeader("X-Forwarded-For");

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("Proxy-Client-IP");
				 
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("WL-Proxy-Client-IP");
				 
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_CLIENT_IP");
				 
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_X_FORWARDED_FOR");
				 
			}
			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getRemoteAddr();
				 
			}
			
		 
		} else if (ip.length() > 15) {
			String[] ips = ip.split(",");
			for (int index = 0; index < ips.length; index++) {
				String strIp = (String) ips[index];
				if (!("unknown".equalsIgnoreCase(strIp))) {
					ip = strIp;
					break;
				}
			}
		}
		return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
	}

	public static String getRemortIP(HttpServletRequest request) {
		if (request.getHeader("x-forwarded-for") == null) {
			return request.getRemoteAddr();
		}
		return request.getHeader("x-forwarded-for");
	}

}
